package config

import (
	"errors"
	"os"
	"path/filepath"
	"strings"

	beeConfig "github.com/astaxie/beego/config"
)

var Configer *Config

type Config struct {
	AppPath     string
	ApiConf     ApiConfig
	DbConf      []DbConfig
	isDev       bool
	beeConfiger beeConfig.Configer
}

// 创建配置文件操作对象
func NewConfiger(fileName string) *Config {
	appPath, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	if strings.Contains(appPath, "yingsheng.com/go-api-server/_test") {
		//处于go test状态下
		appPath = filepath.Join(os.Getenv("GOPATH"), "/src/yingsheng.com/go-api-server/example")
	}

	fileName = filepath.Join(appPath, fileName)

	Configer = &Config{AppPath: appPath}

	var err error
	Configer.beeConfiger, err = beeConfig.NewConfig("ini", fileName)
	if err != nil {
		panic(err)
	}

	// 加载配置
	err = Configer.load()
	if err != nil {
		panic(err)
	}

	Configer.loadDbs()

	return Configer
}

// 是否开发模式
func (c *Config) IsDev() bool {
	return strings.EqualFold(c.ApiConf.RunMode, "dev")
}

func (c *Config) load() error {
	// 系统配置
	c.ApiConf.AppName = c.beeConfiger.String("system::appname")
	c.ApiConf.Version = c.beeConfiger.String("system::version")
	c.ApiConf.LogPath = c.beeConfiger.String("system::logpath")

	c.ApiConf.Dbs = c.beeConfiger.String("system::dbs")
	c.ApiConf.RunMode = c.beeConfiger.String("system::runmode")

	c.ApiConf.Server = c.beeConfiger.String("system::server")
	c.ApiConf.HttpPort = c.beeConfiger.String("system::httpport")
	c.ApiConf.RpcPort = c.beeConfiger.String("system::rpcport")

	c.ApiConf.ModuleName = c.beeConfiger.String("system::modulename")
	c.ApiConf.ModuleInterval = c.beeConfiger.String("system::moduleinterval")

	// 服务治理中间件配置
	c.ApiConf.ConsulServer = c.beeConfiger.String("consul::server")
	c.ApiConf.ConsulPort = c.beeConfiger.String("consul::port")

	// 消息队列中间件配置
	c.ApiConf.MqServer = c.beeConfiger.String("mq::server")
	c.ApiConf.MqPort = c.beeConfiger.String("mq::port")

	errMsg := ""
	switch {
	case len(c.ApiConf.Server) == 0:
		errMsg = "服务地址"
	case len(c.ApiConf.HttpPort) == 0:
		errMsg = "Http端口"
	case len(c.ApiConf.RpcPort) == 0:
		errMsg = "Rpc端口"
	case len(c.ApiConf.ModuleName) == 0:
		errMsg = "微服务名称"
	case len(c.ApiConf.ModuleInterval) == 0:
		// 默认配置10s超时
		c.ApiConf.ModuleInterval = "10s"
	case len(c.ApiConf.ConsulServer) == 0:
		errMsg = "Consul地址"
	case len(c.ApiConf.ConsulPort) == 0:
		errMsg = "Consul端口"
	case len(c.ApiConf.MqServer) == 0:
		errMsg = "Mq地址"
	case len(c.ApiConf.MqPort) == 0:
		errMsg = "Mq端口"
	}

	if len(errMsg) > 0 {
		errMsg = "配置：" + errMsg + " 未设置"
		return errors.New(errMsg)
	}

	c.isDev = strings.EqualFold(c.ApiConf.RunMode, "dev")
	return nil
}

func (c *Config) loadDbs() {
	// 数据库配置
	dbs := strings.Split(c.ApiConf.Dbs, ",")
	c.DbConf = make([]DbConfig, 0, len(dbs))
	if len(dbs) > 0 && len(dbs[0]) > 0 {
		for i := 0; i < len(dbs); i++ {
			dbConfig := DbConfig{
				Type:     c.beeConfiger.String("db-" + dbs[i] + "::type"),
				Alias:    dbs[i],
				Name:     c.beeConfiger.String("db-" + dbs[i] + "::database"),
				Server:   c.beeConfiger.String("db-" + dbs[i] + "::server"),
				Port:     c.beeConfiger.String("db-" + dbs[i] + "::port"),
				User:     c.beeConfiger.String("db-" + dbs[i] + "::user"),
				Password: c.beeConfiger.String("db-" + dbs[i] + "::password"),
			}

			c.DbConf = append(c.DbConf, dbConfig)
		}
	}
}
